Lua委托

TestDelegate.cs

    using UnityEngine;
    using System;
    using System.Collections.Generic;
    using LuaInterface;


    public class TestDelegate: MonoBehaviour
    {
        private string script =
        @"                              
                function DoClick1(go)                
                    print('click1 gameObject is '..go.name)                    
                end

                function DoClick2(go)                
                    print('click2 gameObject is '..go.name)                              
                end                       

                function AddClick1(listener)       
                    if listener.onClick then
                        listener.onClick = listener.onClick + DoClick1                                                    
                    else
                        listener.onClick = DoClick1                      
                    end                
                end

                function AddClick2(listener)
                    if listener.onClick then
                        listener.onClick = listener.onClick + DoClick2                      
                    else
                        listener.onClick = DoClick2
                    end                
                end

                function SetClick1(listener)
                    if listener.onClick then
                        listener.onClick:Destroy()
                    end

                    listener.onClick = DoClick1         
                end

                function RemoveClick1(listener)
                    if listener.onClick then
                        listener.onClick = listener.onClick - DoClick1      
                    else
                        print('empty delegate')
                    end
                end

                function RemoveClick2(listener)
                    if listener.onClick then
                        listener.onClick = listener.onClick - DoClick2    
                    else
                        print('empty delegate')                                
                    end
                end

                --测试重载问题
                function TestOverride(listener)
                    listener:SetOnFinished(TestEventListener.OnClick(DoClick1))
                    listener:SetOnFinished(TestEventListener.VoidDelegate(DoClick2))
                end

                function TestEvent()
                    print('this is a event')
                end

                function AddEvent(listener)
                    listener.onClickEvent = listener.onClickEvent + TestEvent
                end

                function RemoveEvent(listener)
                    listener.onClickEvent = listener.onClickEvent - TestEvent
                end

                local t = {name = 'byself'}

                function t:TestSelffunc()
                    print('callback with self: '..self.name)
                end       

                function AddSelfClick(listener)
                    if listener.onClick then
                        listener.onClick = listener.onClick + TestEventListener.OnClick(t.TestSelffunc, t)
                    else
                        listener.onClick = TestEventListener.OnClick(t.TestSelffunc, t)
                    end   
                end     

                function RemoveSelfClick(listener)
                    if listener.onClick then
                        listener.onClick = listener.onClick - TestEventListener.OnClick(t.TestSelffunc, t)
                    else
                        print('empty delegate')
                    end   
                end
        ";

        LuaState state = null;
        TestEventListener listener = null;

        LuaFunction SetClick1 = null;
        LuaFunction AddClick1 = null;
        LuaFunction AddClick2 = null;
        LuaFunction RemoveClick1 = null;
        LuaFunction RemoveClick2 = null;
        LuaFunction TestOverride = null;
        LuaFunction RemoveEvent = null;
        LuaFunction AddEvent = null;
        LuaFunction AddSelfClick = null;
        LuaFunction RemoveSelfClick = null;

        //需要删除的转LuaFunction为委托,不需要删除的直接加或者等于即可
        void Awake()
        {               
            state = new LuaState();
            state.Start();
            LuaBinder.Bind(state);
            Bind(state);

            state.LogGC = true;
            state.DoString(script);
            GameObject go = new GameObject("TestGo");
            listener = (TestEventListener)go.AddComponent(typeof(TestEventListener));

            SetClick1 = state.GetFunction("SetClick1");
            AddClick1 = state.GetFunction("AddClick1");
            AddClick2 = state.GetFunction("AddClick2");
            RemoveClick1 = state.GetFunction("RemoveClick1");
            RemoveClick2 = state.GetFunction("RemoveClick2");
            TestOverride = state.GetFunction("TestOverride");
            AddEvent = state.GetFunction("AddEvent");
            RemoveEvent = state.GetFunction("RemoveEvent");

            AddSelfClick = state.GetFunction("AddSelfClick");
            RemoveSelfClick = state.GetFunction("RemoveSelfClick");
        }

        void Bind(LuaState L)
        {
            L.BeginModule(null);
            TestEventListenerWrap.Register(state);
            L.EndModule();

            DelegateFactory.dict.Add(typeof(TestEventListener.OnClick), TestEventListener_OnClick);
            DelegateFactory.dict.Add(typeof(TestEventListener.VoidDelegate), TestEventListener_VoidDelegate);
        }

        void CallLuaFunction(LuaFunction func)
        {        
            func.BeginPCall();
            func.Push(listener);
            func.PCall();
            func.EndPCall();                
        }

        //自动生成代码后拷贝过来
        class TestEventListener_OnClick_Event : LuaDelegate
        {
            public TestEventListener_OnClick_Event(LuaFunction func) : base(func) { }

            public void Call(UnityEngine.GameObject param0)
            {
                func.BeginPCall();
                func.Push(param0);
                func.PCall();
                func.EndPCall();
            }
        }

        public static Delegate TestEventListener_OnClick(LuaFunction func, LuaTable self, bool flag)
        {
            if (func == null)
            {
                TestEventListener.OnClick fn = delegate { };
                return fn;
            }

            TestEventListener_OnClick_Event target = new TestEventListener_OnClick_Event(func);
            TestEventListener.OnClick d = target.Call;
            target.method = d.Method;
            return d;
        }

        class TestEventListener_VoidDelegate_Event : LuaDelegate
        {
            public TestEventListener_VoidDelegate_Event(LuaFunction func) : base(func) { }

            public void Call(UnityEngine.GameObject param0)
            {
                func.BeginPCall();
                func.Push(param0);
                func.PCall();
                func.EndPCall();
            }
        }

        public static Delegate TestEventListener_VoidDelegate(LuaFunction func, LuaTable self, bool flag)
        {
            if (func == null)
            {
                TestEventListener.VoidDelegate fn = delegate { };
                return fn;
            }

            TestEventListener_VoidDelegate_Event target = new TestEventListener_VoidDelegate_Event(func);
            TestEventListener.VoidDelegate d = target.Call;
            target.method = d.Method;
            return d;
        }

        void OnGUI()
        {
            if (GUI.Button(new Rect(10, 10, 120, 40), " = OnClick1"))
            {
                CallLuaFunction(SetClick1);
            }
            else if (GUI.Button(new Rect(10, 60, 120, 40), " + Click1"))
            {
                CallLuaFunction(AddClick1);
            }
            else if (GUI.Button(new Rect(10, 110, 120, 40), " + Click2"))
            {
                CallLuaFunction(AddClick2);
            }
            else if (GUI.Button(new Rect(10, 160, 120, 40), " - Click1"))
            {
                CallLuaFunction(RemoveClick1);
            }
            else if (GUI.Button(new Rect(10, 210, 120, 40), " - Click2"))
            {
                CallLuaFunction(RemoveClick2);
            }
            else if (GUI.Button(new Rect(10, 260, 120, 40), "+ Click1 in C#"))
            {
                LuaFunction func = state.GetFunction("DoClick1");
                TestEventListener.OnClick onClick = (TestEventListener.OnClick)DelegateFactory.CreateDelegate(typeof(TestEventListener.OnClick), func);
                listener.onClick += onClick;
            }        
            else if (GUI.Button(new Rect(10, 310, 120, 40), " - Click1 in C#"))
            {
                LuaFunction func = state.GetFunction("DoClick1");
                listener.onClick = (TestEventListener.OnClick)DelegateFactory.RemoveDelegate(listener.onClick, func);
                func.Dispose();
                func = null;
            }
            else if (GUI.Button(new Rect(10, 360, 120, 40), "OnClick"))
            {
                if (listener.onClick != null)
                {
                    listener.onClick(gameObject);
                }
                else
                {
                    Debug.Log("empty delegate!!");
                }
            }
            else if (GUI.Button(new Rect(10, 410, 120, 40), "Override"))
            {
                CallLuaFunction(TestOverride);
            }
            else if (GUI.Button(new Rect(10, 460, 120, 40), "Force GC"))
            {
                //自动gc log: collect lua reference name , id xxx in thread 
                state.LuaGC(LuaGCOptions.LUA_GCCOLLECT, 0);
                GC.Collect();
            }
            else if (GUI.Button(new Rect(10, 510, 120, 40), "event +"))
            {
                CallLuaFunction(AddEvent);
            }
            else if (GUI.Button(new Rect(10, 560, 120, 40), "event -"))
            {
                CallLuaFunction(RemoveEvent);
            }
            else if (GUI.Button(new Rect(10, 610, 120, 40), "event call"))
            {
                listener.OnClickEvent(gameObject);
            }
            else if (GUI.Button(new Rect(200, 10, 120, 40), "+self call"))
            {
                CallLuaFunction(AddSelfClick);
            }
            else if (GUI.Button(new Rect(200, 60, 120, 40), "-self call"))
            {
                CallLuaFunction(RemoveSelfClick);
            }
        }

        void Update()
        {
            state.Collect();
            state.CheckTop();        
        }

        void SafeRelease(ref LuaFunction luaRef)
        {
            if (luaRef != null)
            {
                luaRef.Dispose();
                luaRef = null;
            }
        }

        void OnDestroy()
        {
            SafeRelease(ref AddClick1);
            SafeRelease(ref AddClick2);
            SafeRelease(ref RemoveClick1);
            SafeRelease(ref RemoveClick2);
            SafeRelease(ref SetClick1);
            SafeRelease(ref TestOverride);
            state.Dispose();
            state = null;
        }
    }

TestEventListener.cs

    using UnityEngine;
    using System;
    using System.Collections;
    using LuaInterface;

    public class TestEventListener : MonoBehaviour
    {
        public delegate void VoidDelegate(GameObject go);
        public delegate void OnClick(GameObject go);    
        public OnClick onClick = delegate { };

        public event OnClick onClickEvent = delegate { };

        public Func<bool> TestFunc = null;

        public void SetOnFinished(OnClick click)
        {
            Debugger.Log("SetOnFinished OnClick");
        }

        public void SetOnFinished(VoidDelegate click)
        {
            Debugger.Log("SetOnFinished VoidDelegate");
        }

        [NoToLuaAttribute]
        public void OnClickEvent(GameObject go)
        {
            onClickEvent(go);
        }
    }

TestEventListenerWrap.cs

    //this source code was auto-generated by tolua#, do not modify it
    using System;
    using LuaInterface;

    public class TestEventListenerWrap
    {
        public static void Register(LuaState L)
        {
            L.BeginClass(typeof(TestEventListener), typeof(UnityEngine.MonoBehaviour));
            L.RegFunction("SetOnFinished", SetOnFinished);
            L.RegFunction("__eq", op_Equality);
            L.RegFunction("__tostring", Lua_ToString);
            L.RegVar("onClick", get_onClick, set_onClick);
            L.RegVar("onClickEvent", get_onClickEvent, set_onClickEvent);
            L.RegFunction("OnClick", TestEventListener_OnClick);
            L.RegFunction("VoidDelegate", TestEventListener_VoidDelegate);
            L.EndClass();
        }

        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int SetOnFinished(IntPtr L)
        {
            try
            {
                int count = LuaDLL.lua_gettop(L);

                if (count == 2 && TypeChecker.CheckTypes(L, 1, typeof(TestEventListener), typeof(TestEventListener.VoidDelegate)))
                {
                    TestEventListener obj = (TestEventListener)ToLua.ToObject(L, 1);
                    TestEventListener.VoidDelegate arg0 = null;
                    LuaTypes funcType2 = LuaDLL.lua_type(L, 2);

                    if (funcType2 != LuaTypes.LUA_TFUNCTION)
                    {
                         arg0 = (TestEventListener.VoidDelegate)ToLua.ToObject(L, 2);
                    }
                    else
                    {
                        LuaFunction func = ToLua.ToLuaFunction(L, 2);
                        arg0 = DelegateFactory.CreateDelegate(typeof(TestEventListener.VoidDelegate), func) as TestEventListener.VoidDelegate;
                    }

                    obj.SetOnFinished(arg0);
                    return 0;
                }
                else if (count == 2 && TypeChecker.CheckTypes(L, 1, typeof(TestEventListener), typeof(TestEventListener.OnClick)))
                {
                    TestEventListener obj = (TestEventListener)ToLua.ToObject(L, 1);
                    TestEventListener.OnClick arg0 = null;
                    LuaTypes funcType2 = LuaDLL.lua_type(L, 2);

                    if (funcType2 != LuaTypes.LUA_TFUNCTION)
                    {
                         arg0 = (TestEventListener.OnClick)ToLua.ToObject(L, 2);
                    }
                    else
                    {
                        LuaFunction func = ToLua.ToLuaFunction(L, 2);
                        arg0 = DelegateFactory.CreateDelegate(typeof(TestEventListener.OnClick), func) as TestEventListener.OnClick;
                    }

                    obj.SetOnFinished(arg0);
                    return 0;
                }
                else
                {
                    return LuaDLL.luaL_throw(L, "invalid arguments to method: TestEventListener.SetOnFinished");
                }
            }
            catch(Exception e)
            {
                return LuaDLL.toluaL_exception(L, e);
            }
        }

        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int op_Equality(IntPtr L)
        {
            try
            {
                ToLua.CheckArgsCount(L, 2);
                UnityEngine.Object arg0 = (UnityEngine.Object)ToLua.ToObject(L, 1);
                UnityEngine.Object arg1 = (UnityEngine.Object)ToLua.ToObject(L, 2);
                bool o = arg0 == arg1;
                LuaDLL.lua_pushboolean(L, o);
                return 1;
            }
            catch(Exception e)
            {
                return LuaDLL.toluaL_exception(L, e);
            }
        }

        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int Lua_ToString(IntPtr L)
        {
            object obj = ToLua.ToObject(L, 1);

            if (obj != null)
            {
                LuaDLL.lua_pushstring(L, obj.ToString());
            }
            else
            {
                LuaDLL.lua_pushnil(L);
            }

            return 1;
        }

        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int get_onClick(IntPtr L)
        {
            object o = null;

            try
            {
                o = ToLua.ToObject(L, 1);
                TestEventListener obj = (TestEventListener)o;
                TestEventListener.OnClick ret = obj.onClick;
                ToLua.Push(L, ret);
                return 1;
            }
            catch(Exception e)
            {
                return LuaDLL.toluaL_exception(L, e, o == null ? "attempt to index onClick on a nil value" : e.Message);
            }
        }

        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int get_onClickEvent(IntPtr L)
        {
            ToLua.Push(L, new EventObject("TestEventListener.onClickEvent"));
            return 1;
        }

        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int set_onClick(IntPtr L)
        {
            object o = null;

            try
            {
                o = ToLua.ToObject(L, 1);
                TestEventListener obj = (TestEventListener)o;
                TestEventListener.OnClick arg0 = null;
                LuaTypes funcType2 = LuaDLL.lua_type(L, 2);

                if (funcType2 != LuaTypes.LUA_TFUNCTION)
                {
                     arg0 = (TestEventListener.OnClick)ToLua.CheckObject(L, 2, typeof(TestEventListener.OnClick));
                }
                else
                {
                    LuaFunction func = ToLua.ToLuaFunction(L, 2);
                    arg0 = DelegateFactory.CreateDelegate(typeof(TestEventListener.OnClick), func) as TestEventListener.OnClick;
                }

                obj.onClick = arg0;
                return 0;
            }
            catch(Exception e)
            {
                return LuaDLL.toluaL_exception(L, e, o == null ? "attempt to index onClick on a nil value" : e.Message);
            }
        }

        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int set_onClickEvent(IntPtr L)
        {
            try
            {
                TestEventListener obj = (TestEventListener)ToLua.CheckObject(L, 1, typeof(TestEventListener));
                EventObject arg0 = null;

                if (LuaDLL.lua_isuserdata(L, 2) != 0)
                {
                    arg0 = (EventObject)ToLua.ToObject(L, 2);
                }
                else
                {
                    return LuaDLL.luaL_throw(L, "The event 'TestEventListener.onClickEvent' can only appear on the left hand side of += or -= when used outside of the type 'TestEventListener'");
                }

                if (arg0.op == EventOp.Add)
                {
                    TestEventListener.OnClick ev = (TestEventListener.OnClick)DelegateFactory.CreateDelegate(typeof(TestEventListener.OnClick), arg0.func);
                    obj.onClickEvent += ev;
                }
                else if (arg0.op == EventOp.Sub)
                {
                    TestEventListener.OnClick ev = (TestEventListener.OnClick)LuaMisc.GetEventHandler(obj, typeof(TestEventListener), "onClickEvent");
                    Delegate[] ds = ev.GetInvocationList();
                    LuaState state = LuaState.Get(L);

                    for (int i = 0; i < ds.Length; i++)
                    {
                        ev = (TestEventListener.OnClick)ds[i];
                        LuaDelegate ld = ev.Target as LuaDelegate;

                        if (ld != null && ld.func == arg0.func)
                        {
                            obj.onClickEvent -= ev;
                            state.DelayDispose(ld.func);
                            break;
                        }
                    }

                    arg0.func.Dispose();
                }

                return 0;
            }
            catch(Exception e)
            {
                return LuaDLL.toluaL_exception(L, e);
            }
        }

        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int TestEventListener_OnClick(IntPtr L)
        {
            try
            {
                LuaFunction func = ToLua.CheckLuaFunction(L, 1);
                Delegate arg1 = DelegateFactory.CreateDelegate(typeof(TestEventListener.OnClick), func);
                ToLua.Push(L, arg1);
                return 1;
            }
            catch(Exception e)
            {
                return LuaDLL.toluaL_exception(L, e);
            }
        }

        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int TestEventListener_VoidDelegate(IntPtr L)
        {
            try
            {
                LuaFunction func = ToLua.CheckLuaFunction(L, 1);
                Delegate arg1 = DelegateFactory.CreateDelegate(typeof(TestEventListener.VoidDelegate), func);
                ToLua.Push(L, arg1);
                return 1;
            }
            catch(Exception e)
            {
                return LuaDLL.toluaL_exception(L, e);
            }
        }
    }

🔚

results matching ""

    No results matching ""